// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Admin.NET.Application.Entity;
using Coravel.Invocable;
using DocumentFormat.OpenXml.Bibliography;
using Elastic.Clients.Elasticsearch;
using MathNet.Numerics.Distributions;
using Microsoft.IdentityModel.Logging;
using MyDemo.Application.Service.Plc;
using SL.NET.Core.Service;
using System.DirectoryServices.Protocols;
using System.Linq;
using System.Threading;
using WCS.Application.Entity.Warehous;
using static MyDemo.Application.Service.Plc.MqttService;

namespace WCS.Application.Service.Rcs;
/// <summary>
/// 设备动作调度
/// </summary>
/// 
/*[ApiDescriptionSettings(groups: ApplicationConst.GroupName, Order = 15)]
[AllowAnonymous]*/
public class ActionOperationService : IInvocable
{
    // IDynamicApiController, ITransient
    //mqtt

    private readonly IServiceScopeFactory _serviceScopeFactory;
    private readonly MqttService _mqttClientService;
    private readonly SqlSugarRepository<AgvactionsEntity> _agvactionsRepo;
    private readonly SqlSugarRepository<InventoryManagementEntity> _inventoryManagementEntityRepo;
    private readonly SqlSugarRepository<WCSTaskManagementEntity> _wscTaskEntityRepo;
    private readonly SqlSugarRepository<OrderDetailEntity> _outboundOrderDetailRepo;
    private readonly SqlSugarRepository<OrderInfoEntity> _outboundOrderInfoRepo;
    private readonly DispatchService _dispatchService;
    private readonly SysCacheService _sysCacheService;

    //获取任务表信息
    private readonly SqlSugarRepository<WCSTaskManagementEntity> _wcsTaskEntity;
    public ActionOperationService(MqttService mqttClientService,
        IServiceScopeFactory serviceScopeFactory
        //SqlSugarRepository<AgvactionsEntity> agvactionsRepo,
        //DispatchService dispatchService, 
        //SysCacheService sysCacheService
        //SqlSugarRepository<WCSTaskManagementEntity> wcsTaskEntity
        )
    {
        _serviceScopeFactory = serviceScopeFactory;
        _mqttClientService = mqttClientService;

        using var serviceScope = _serviceScopeFactory.CreateScope();
        _agvactionsRepo = serviceScope.ServiceProvider.GetService<SqlSugarRepository<AgvactionsEntity>>();
        _inventoryManagementEntityRepo = serviceScope.ServiceProvider.GetService<SqlSugarRepository<InventoryManagementEntity>>();
        _wscTaskEntityRepo = serviceScope.ServiceProvider.GetService<SqlSugarRepository<WCSTaskManagementEntity>>();
        _outboundOrderDetailRepo = serviceScope.ServiceProvider.GetService<SqlSugarRepository<OrderDetailEntity>>();
        _outboundOrderInfoRepo = serviceScope.ServiceProvider.GetService<SqlSugarRepository<OrderInfoEntity>>();
        _dispatchService = serviceScope.ServiceProvider.GetService<DispatchService>();
        _sysCacheService = serviceScope.ServiceProvider.GetService<SysCacheService>();

        ////_agvactionsRepo = agvactionsRepo;
        //_dispatchService = dispatchService;
        //_sysCacheService = sysCacheService;
        //_wcsTaskEntity = wcsTaskEntity;
    }
    /*    [ApiDescriptionSettings(Name = "DispatchPlan"), HttpGet]
        [DisplayName("查询动作表状态下发设备")]
        public async Task ProcessLastActionStatusAsync()
        {
        }*/
    public async Task Invoke()
    {
        SerilogHelper.WriteLog("ActionOperationService", "start");
        /* while (true)*/
        try
        {
            if (_sysCacheService.Get<bool>("hasTask"))
            {
                SerilogHelper.WriteLog("ActionOperationService", "上个队列未执行完");
                return;
            }

            try
            {
                _sysCacheService.Set("hasTask", true, TimeSpan.FromSeconds(3600));
                // 不同的任务分组要开多线程并发执行，逻辑待修改

                // 查询所有待执行任务
                var openTaskAction = await _agvactionsRepo.AsQueryable()
                   .Where(a => a.Status != ActionStatusEnum.Completed && a.Status != ActionStatusEnum.Cancelled)
                   .OrderBy(a => a.Id)
                   .ToListAsync();


                // 创建任务列表
                var tasks = new List<Task>();
                var taskGroups = openTaskAction
                    .GroupBy(it => it.TaskId)
                    .Select(g => g.Key).ToList();
                //var taskGroups = openTaskAction.GroupBy(it => it.TaskId).Select(it => it.id).ToList();
                var tasksAll = await _agvactionsRepo.AsQueryable()
                   .Where(a => taskGroups.Contains(a.TaskId))
                   .OrderBy(a => a.Id)
                   .ToListAsync(); ;
                foreach (var group in taskGroups)
                {
                    // 为每个任务组创建一个处理任务
                    tasks.Add(Task.Run(async () =>
                    {
                        try
                        {
                            await ProcessTaskGroup(group, tasksAll.Where(it => it.TaskId == group).ToList());
                        }
                        catch (Exception ex)
                        {
                            LogHelper.WriteErrorLog("ActionOperationService", ex);
                        }
                    }));
                }

                await Task.WhenAll(tasks);

            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog("ActionOperationService", ex);
            }
            finally
            {
                _sysCacheService.Remove("hasTask");
            }
        }
        catch (Exception ex)
        {
            LogHelper.WriteErrorLog("ActionOperationService", ex);
        }

        SerilogHelper.WriteLog("ActionOperationService", "end");

    }


    // 处理单个任务组的方法
    private async Task ProcessTaskGroup(string taskid, List<AgvactionsEntity> taskGroup)
    {
        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "start");
        try
        {
            //var value = taskGroup.value
            // 查询最后一个任务
            //var lastTaskAction = await _agvactionsRepo.AsQueryable()
            //   .OrderBy(a => a.Id)
            //   .Where(a => a.Status != ActionStatusEnum.Completed && a.Status != ActionStatusEnum.Cancelled)
            //   .FirstAsync();
            var lastTaskAction = taskGroup
                .Where(a => a.Status != ActionStatusEnum.Completed && a.Status != ActionStatusEnum.Cancelled)
                .FirstOrDefault();
            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "lastTaskAction", JsonHelper.ObjectToJson(lastTaskAction));
            if (lastTaskAction is not null)
            {

                // 如果任务是动作，则下发动作指令给设备
                if (lastTaskAction.ActionType == AgvActionType.Movement)
                {
                    //查询反馈信息
                    //var lastAction = await _agvactionsRepo.AsQueryable()
                    //   .OrderBy(a => a.Id).Where(a => a.ActionType == AgvActionType.Feedback && a.Status != ActionStatusEnum.Completed && a.Status != ActionStatusEnum.Cancelled)
                    //   .FirstAsync(); 
                    var lastAction = taskGroup
                       .OrderBy(a => a.Id)
                       .Where(a => a.ActionType == AgvActionType.Feedback && a.Status != ActionStatusEnum.Completed && a.Status != ActionStatusEnum.Cancelled)
                       .FirstOrDefault();
                    //获取当前任务的第一个反馈 
                    //var last = await _agvactionsRepo.AsQueryable().OrderBy(a => a.Actionsort).Where(a => a.TaskId == lastAction.TaskId && a.ActionType == AgvActionType.Feedback && a.Status != ActionStatusEnum.Completed && a.AgvTaskid == lastAction.AgvTaskid).FirstAsync();
                    var last = taskGroup
                        .OrderBy(a => a.Actionsort)
                        .Where(a => a.TaskId == lastAction.TaskId
                            && a.ActionType == AgvActionType.Feedback
                            && a.Status != ActionStatusEnum.Completed
                            && a.AgvTaskid == lastAction.AgvTaskid)
                        .FirstOrDefault();

                    //查询反馈信息对应的动作
                    //var lastActions = await _agvactionsRepo.AsQueryable()
                    //    .OrderBy(a => a.Id)
                    //   .Where(a => a.AgvTaskid == last.AgvTaskid && a.ActionType == AgvActionType.Movement)
                    //   .FirstAsync();
                    var lastActions = taskGroup
                        .OrderBy(a => a.Id)
                       .Where(a => a.AgvTaskid == last.AgvTaskid && a.ActionType == AgvActionType.Movement)
                       .FirstOrDefault();
                    if (lastAction == null)
                    {
                        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "没有找到任何动作记录");
                        return;
                    }

                    SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "lastAction", JsonHelper.ObjectToJson(lastAction));
                    switch (last.Status)
                    {
                        //待处理
                        case ActionStatusEnum.Pending:
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"向MQTT发送动作指令: {lastActions.AgvTaskid}");
                            var ss = await _mqttClientService.PublishMessageAsync(
                                 //任务id
                                 (string)lastActions.TaskId,
                                 //动作任务id
                                 (int)lastActions.AgvTaskid,
                                 //托盘码
                                 lastActions.Palletcode,
                                 //设备编号
                                 lastActions.DeviceId,
                                 //起始点位
                                 lastActions.StartPosition,
                                 //目标点位
                                 lastActions.TargetPosition,
                                 //动作执行层
                                 (int)lastActions.TargetFloor,
                                 //起始目标中间的点
                                 //lastAction.Routepoint,
                                 //动作类型 (int)
                                 GetMqttActionType((ActionTypeEnum)lastActions.ActionGroupType)
                             );
                            if (ss)
                            {
                                SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"动作指令执行成功");
                                lastActions.Status = ActionStatusEnum.Completed;
                                await _agvactionsRepo.UpdateAsync(lastActions);

                            }
                            else
                            {
                                SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"动作指令执行失败");
                            }

                            break;
                        case ActionStatusEnum.Completed:
                            // 已成功状态逻辑
                            break;

                        case ActionStatusEnum.Failed://失败的情况就会去重新生成新的路径
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"发现失败动作: {lastActions.TaskId}，开始处理同组任务");

                            // 1. 将同组的未完成任务全部标记为已取消
                            await CancelPendingActionsInSameGroup(lastActions);

                            // 2. 重新制定该组的动作
                            await ReplanActionsForGroup(lastActions);
                            break;

                        default:
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"未知状态: {last.Status}");
                            break;
                    }

                }

                // 如果任务是反馈，则读取设备的状态，判断是否已完成
                else if (lastTaskAction.ActionType == AgvActionType.Feedback)
                {

                    var deriveId = lastTaskAction.DeviceId;
                    // 提升机
                    if (lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationup || lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationup)
                    {
                        deriveId = lastTaskAction.TargetPosition;
                    }

                    var deriveInfo = _sysCacheService.Get<DerivesInfo>(deriveId);

                    SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "deriveInfo", JsonHelper.ObjectToJson(deriveInfo));
                    // 如果设备状态为空闲，并且任务号与动作任务ID相同，则认为动作已完成，更新反馈状态

                    // 提升机上货
                    if (lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationup)
                    {
                        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"提升机上货反馈：{lastTaskAction.ActionGroupType}");
                        // 判断设备的反馈状态
                        var deviceResponseCache = _sysCacheService.Get<string>(lastTaskAction.TargetPosition + "Response");
                        if (deviceResponseCache != null && deviceResponseCache.Contains("已反馈"))
                        {
                            lastTaskAction.Status = ActionStatusEnum.Completed;
                            await _agvactionsRepo.UpdateAsync(lastTaskAction);

                            // 清除设备任务状态
                            _sysCacheService.Remove(lastTaskAction.TargetPosition + "Response");
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"提升机上货 动作完成");
                        }
                    }
                    // 提升机下货
                    else if (lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationdown)
                    {
                        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"提升机下货反馈：{lastTaskAction.ActionGroupType}");
                        // 判断设备的反馈状态
                        var deviceResponseCache = _sysCacheService.Get<string>(lastTaskAction.TargetPosition + "Response");
                        if (deviceResponseCache != null && deviceResponseCache.Contains("已反馈"))
                        {
                            lastTaskAction.Status = ActionStatusEnum.Completed;
                            await _agvactionsRepo.UpdateAsync(lastTaskAction);

                            // 清除设备任务状态
                            _sysCacheService.Remove(lastTaskAction.TargetPosition + "Response");
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"提升机下货动作完成");
                        }

                        // 出库最后一个动作
                        if (lastTaskAction.Istype == "outbound" && lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationdown)
                        {
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"出库最后一个动作：{lastTaskAction.ActionGroupType}");
                            // 出库完成后的逻辑
                            // 删除库存
                            var rtInventoryManagementEntityRepo = await _inventoryManagementEntityRepo
                                .AsDeleteable()
                                .Where(it => it.Palcode == lastTaskAction.Palletcode).ExecuteCommandAsync();
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"库存删除结果：{rtInventoryManagementEntityRepo}");

                            // 更新WCS任务表
                            var rtwscTaskEntityRepo = await _wscTaskEntityRepo
                                 .AsUpdateable()
                                .SetColumns(it => it.Status == TaskStatusEnmu.Completed)
                                .Where(it => it.TaskNumber == lastTaskAction.TaskId)
                                .ExecuteCommandAsync();
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"更新WCS任务表结果：{rtwscTaskEntityRepo}");

                            // 更新领料单托盘出库任务明细
                            var rtoutboundOrderDetailRepo = await _outboundOrderDetailRepo
                                 .AsUpdateable()
                                .SetColumns(it => it.Status == 2)
                                .Where(it => it.PickingNumber == lastTaskAction.TaskId && it.Tray == lastTaskAction.Palletcode)
                                .ExecuteCommandAsync();
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"更新领料单托盘出库任务结果：{rtwscTaskEntityRepo}");

                            // 更新领料单状态
                            var openDetailOrder = await _outboundOrderDetailRepo
                                .AsQueryable()
                                .Where(it => it.PickingNumber == lastTaskAction.TaskId && it.Status == 0 && it.Status == 1)
                                .FirstAsync();
                            if (openDetailOrder is null)
                            {
                                var rtoutboundOrderInfoRepo = await _outboundOrderInfoRepo
                                     .AsUpdateable()
                                     .SetColumns(it => it.OrderStatus == OrderStatusEnum.Completed)
                                    .Where(it => it.OrderId == lastTaskAction.TaskId)
                                     .ExecuteCommandAsync();
                            }
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"更新领料单状态结果：{rtwscTaskEntityRepo}");

                        }
                    }
                    // RGV 举货
                    else if (lastTaskAction.ActionGroupType == ActionTypeEnum.Lifting)
                    {
                        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"RGV举货反馈：{lastTaskAction.ActionGroupType}");
                        if (deriveInfo?.DeviceStatus == 0 && deriveInfo?.TaskId.GetCInt() == lastTaskAction.AgvTaskid && deriveInfo?.UpStatus == 2)
                        {
                            lastTaskAction.Status = ActionStatusEnum.Completed;
                            await _agvactionsRepo.UpdateAsync(lastTaskAction);
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"RGV举货动作完成");
                        }
                    }
                    // RGV 放货
                    else if (lastTaskAction.ActionGroupType == ActionTypeEnum.Unloading)
                    {
                        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"RGV放货：{lastTaskAction.ActionGroupType}");
                        if (deriveInfo?.DeviceStatus == 0 && deriveInfo?.TaskId.GetCInt() == lastTaskAction.AgvTaskid && deriveInfo?.UpStatus == 1)
                        {
                            lastTaskAction.Status = ActionStatusEnum.Completed;
                            await _agvactionsRepo.UpdateAsync(lastTaskAction);
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"RGV放货动作完成");
                        }
                    }
                    // RGV 移动
                    else
                    {
                        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"RGV移动反馈：{lastTaskAction.ActionGroupType}");
                        if (deriveInfo?.DeviceStatus == 0 && deriveInfo?.TaskId.GetCInt() == lastTaskAction.AgvTaskid && deriveInfo?.LocationPoint == lastTaskAction.TargetPosition)
                        {
                            lastTaskAction.Status = ActionStatusEnum.Completed;
                            await _agvactionsRepo.UpdateAsync(lastTaskAction);
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"RGV移动动作完成");

                            //查询反馈信息对应的动作
                            var lastActions = taskGroup
                            .OrderBy(a => a.Id)
                               .Where(a => a.AgvTaskid == lastTaskAction.AgvTaskid && a.ActionType == AgvActionType.Movement)
                               .FirstOrDefault();
                            //更改redis路径缓存
                            await RemoveRedispoint(taskid, lastTaskAction.DeviceId, lastActions.Routepoint);

                        }

                        // 入库的最后一个动作
                        if (lastTaskAction.Istype == "inbound" && lastTaskAction.ActionGroupType == ActionTypeEnum.OutLocation)
                        {
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"入库最后一个动作：{lastTaskAction.ActionGroupType}");
                            // 入库完成后，更新库存冻结状态为正常
                            var stocksRt = await _inventoryManagementEntityRepo
                                .AsUpdateable()
                                .SetColumns(it => it.Status == InventoryStatus.正常)
                                .Where(it => it.Palcode == lastTaskAction.Palletcode)
                                .ExecuteCommandAsync();
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"库存更新结果：{stocksRt}");

                            // 更新WCS任务表
                            var wcstaskRt = await _wscTaskEntityRepo
                                 .AsUpdateable()
                                .SetColumns(it => it.Status == TaskStatusEnmu.Completed)
                                .Where(it => it.TaskNumber == lastTaskAction.TaskId)
                                .ExecuteCommandAsync();
                            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", $"WCS任务表更新结果：{wcstaskRt}");

                        }
                    }

                    //// 如果设备状态为异常，取消动作
                    //if (deriveInfo?.DeviceEnable == false)
                    //{
                    //    lastTaskAction.Status = ActionStatusEnum.Completed;
                    //    await _agvactionsRepo.UpdateAsync(lastTaskAction);
                    //}
                }
            }

        }
        catch (Exception ex)
        {
            LogHelper.WriteErrorLog($"ProcessTaskGroup_{taskid}", ex);
        }
        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "end");
    }

    /// <summary>
    /// 清掉redis数据
    /// </summary>
    /// <param name="DeviceId">设备id</param>
    /// <param name="Routepoint">途径路径</param>
    /// <returns></returns>
    public async Task RemoveRedispoint(string taskid, string DeviceId, string Routepoint)
    {
        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "Routepoint", Routepoint);
        var sdsds = new List<(int x, int y)>();
        //每个redis的数据
        var activeBlockedPoints = new List<(int x, int y)>();
        //var  activeBlockedPoints = "";

        List<string> Routepointlist = JsonHelper.JsonToObject<List<string>>(Routepoint);
        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "Routepointlist", JsonHelper.ObjectToJson(Routepointlist));
        List<(int x, int y)> result = new List<(int x, int y)>();

        foreach (string item in Routepointlist)
        {
            string[] parts = item.Split(',');
            int x = int.Parse(parts[0]);
            int y = int.Parse(parts[1]);
            result.Add((x, y));
        }
        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "result", JsonHelper.ObjectToJson(result));
        var json = _sysCacheService.Get<string>(DeviceId + "Point");
        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "json", json);
        //activeBlockedPoints = _sysCacheService.Get<List<(int x,int y)>>(x.DeviceId);
        activeBlockedPoints = JsonHelper.JsonToObject<List<(int x, int y)>>(json);
        var RoutepointList = new List<(int x, int y)>();
        foreach (var item in result)
        {
            var index = activeBlockedPoints.IndexOf(item);
            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "item", JsonHelper.ObjectToJson(item));
            SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "index", index.ToString());
            //var point  = activeBlockedPoints.Find(it => it.);
            activeBlockedPoints.Remove(item);
        }
        SerilogHelper.WriteLog($"ProcessTaskGroup_{taskid}", "activeBlockedPoints", JsonHelper.ObjectToJson(activeBlockedPoints));
        var updatedJson = JsonHelper.ObjectToJson(activeBlockedPoints);
        _sysCacheService.Set(DeviceId + "Point", updatedJson);

        result = null;
    }



    // 将系统内部动作类型映射到MQTT动作类型的辅助方法
    private int GetMqttActionType(ActionTypeEnum actionType)
    {
        // 根据实际业务需求映射动作类型
        switch (actionType)
        {
            case ActionTypeEnum.HoistOperationup: return 0; // 提升机升货
            case ActionTypeEnum.Pickup: return 1; // 取货
            case ActionTypeEnum.Lifting: return 2; // 举货
            case ActionTypeEnum.StorageDelivery: return 3; // 送到库位点位
            case ActionTypeEnum.Unloading: return 4; // 卸货
            case ActionTypeEnum.Delivery: return 5; // 出库送货
            case ActionTypeEnum.HoistOperationdown: return 6; // 提升机下货
            case ActionTypeEnum.InLocation: return 7; // 入库位
            case ActionTypeEnum.OutLocation: return 8; // 出库位
            case ActionTypeEnum.BeforeLifting: return 9; //入库位前举货
            case ActionTypeEnum.recharge: return 10; //充电
            default: return 0; // 默认使用提升机升货类型
        }
    }
    // 取消同组的未完成任务
    private async Task CancelPendingActionsInSameGroup(AgvactionsEntity failedActions)
    {
        var pendingActions = await _agvactionsRepo.AsQueryable()
            .Where(a =>
                a.TaskId == failedActions.TaskId &&
                a.ActionGroupType == failedActions.ActionGroupType &&
                a.Status != ActionStatusEnum.Completed)
            .ToListAsync();

        foreach (var action in pendingActions)
        {
            action.Status = ActionStatusEnum.Cancelled;
            await _agvactionsRepo.UpdateAsync(action);
            SerilogHelper.WriteLog($"ProcessTaskGroup_{failedActions.TaskId}", $"任务 {action.Id} 已取消，原状态: {action.Status}");
        }
    }

    // 重新制定该组的动作
    private async Task ReplanActionsForGroup(AgvactionsEntity failedActions)
    {
        try
        {
            // 根据任务类型选择不同的重新规划逻辑
            switch (failedActions.Istype)
            {
                case "inbound":
                    // 重新规划取货动作
                    await RukuActions(failedActions);
                    break;

                case "outbound":
                    // 重新规划送货动作
                    await ChukuActions(failedActions);
                    break;

                // 其他类型的动作组...
                default:
                    SerilogHelper.WriteLog($"ProcessTaskGroup_{failedActions.TaskId}", $"不支持重新规划的动作组类型: {failedActions.ActionGroupType}");
                    break;
            }
        }
        catch (Exception ex)
        {
            SerilogHelper.WriteLog($"ProcessTaskGroup_{failedActions.TaskId}", $"重新规划动作失败: {ex.Message}");
            // 可以添加重试逻辑或告警机制
        }
    }

    // 重新规划入库个别动作
    private async Task RukuActions(AgvactionsEntity failedAction)
    {
        //获取agv当前点位
        var deviceData = _sysCacheService.Get<DerivesInfo>(failedAction.DeviceId);
        //获取任务起点
        var HoistOpening = _wcsTaskEntity.GetList().Where(c => c.TaskNumber == failedAction.TaskId).Select(c => c.HoistOpening);
        // 假设我们有一个重新规划取货的方法
        var request = new InboundRequest
        {
            TaskId = failedAction.TaskId,
            AgvCode = failedAction.DeviceId,
            /*AgvCurrentPos = deviceData.LocationPoint,
            Startcoord =HoistOpening,*/
            AgvCurrentPos = "3,14",
            Startcoord = "102",
            TargetFloor = (int)failedAction.TargetFloor,
            TargetPointCoord = failedAction.GroupTargetPosition,
            StoragePosCoord = failedAction.GroupTargetPosition,
            Palletcode = failedAction.Palletcode,
            Speed = 1,
            Agvtype = failedAction.Istype
        };
        //动作分组转换int
        int ss = GetMqttActionType(failedAction.ActionGroupType);
        // 调用入库计划生成方法
        await _dispatchService.AgainInboundRequest(request, ss, failedAction.Actionsort);
    }

    // 重新规划出库个别动作
    private async Task ChukuActions(AgvactionsEntity failedAction)
    {   //获取agv当前点位
        var deviceData = _sysCacheService.Get<DerivesInfo>(failedAction.DeviceId);
        //获取任务起点 其实点位比如（12,22,32,42,52）
        var HoistOpening = _wcsTaskEntity.GetList().Where(c => c.TaskNumber == failedAction.TaskId).Select(c => c.HoistOpening);
        // 类似地，实现送货动作的重新规划
        var request = new OutboundRequest
        {
            TaskId = failedAction.TaskId,
            AgvCode = failedAction.DeviceId,
            AgvCurrentPos = deviceData.LocationPoint,
            Startcoord = Convert.ToString(HoistOpening),
            TargetFloor = (int)failedAction.TargetFloor,
            TargetPointCoord = failedAction.GroupTargetPosition,
            StoragePosCoord = failedAction.GroupTargetPosition,
            Palletcode = failedAction.Palletcode,
            Speed = 1,
            Agvtype = failedAction.Istype
        };
        //动作分组转换int
        int ss = GetMqttActionType(failedAction.ActionGroupType);
        // 调用入库计划生成方法
        await _dispatchService.AgainCreateOutboundPlan(request, ss, failedAction.Actionsort);
        SerilogHelper.WriteLog($"ProcessTaskGroup_{failedAction.TaskId}", $"已重新规划送货动作组: {failedAction.TaskId}");
    }


}
